package com.make.house.api.utils;

import java.util.*;

/**
 * Created by xujun on 2018/8/27.
 * 微信下单必要的接口
 */
public class WxOrderUtils {

    public static final String MINI_APP_ID = "wx7dd54d1d27987209"; //小程序的APPID
    public static final String MCH_ID = "1513339531"; //商户的id，支付申请成功后会有
    public static final String MCH_KEY = ""; //商户的签名，申请成功后会有
    public static final String SIGN_TYPE = "MD5"; //这里的签名信息主要是md5
    public static final int NONCE_STR_LENGTH = 15; //这里默认去取15位随机数，微信文档限制小于3位，这个随机数目的是防止刷接口
    public static final int ORDER_EXPIRE_TIME_MINUTE = 30;  //订单有效时长30分钟

    //获取指定位数的随机字符串(包含小写字母、大写字母、数字,0<length)
    //主要是获取微信支付需要的 nonce_str 字段
    public static String getRandomString(int length) {
        //随机字符串的随机字符库
        String KeyString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder sb = new StringBuilder();
        int len = KeyString.length();
        for (int i = 0; i < length; i++) {
            sb.append(KeyString.charAt((int) Math.round(Math.random() * (len - 1))));
        }
        return sb.toString();
    }

    /**
     * 通过参数获取支付下订单的签名信息
     * 注意点
     * 第一步，设所有发送或者接收到的数据为集合M，将集合M内非空参数值的参数按照参数名ASCII码从小到大排序（字典序），使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串stringA。
     * 特别注意以下重要规则：
     * ◆ 参数名ASCII码从小到大排序（字典序）；
     * ◆ 如果参数的值为空不参与签名；
     * ◆ 参数名区分大小写；
     * ◆ 验证调用返回或微信主动通知签名时，传送的sign参数不参与签名，将生成的签名与该sign值作校验。
     * ◆ 微信接口可能增加字段，验证签名时必须支持增加的扩展字段
     * 第二步，在stringA最后拼接上key得到stringSignTemp字符串，并对stringSignTemp进行MD5运算，再将得到的字符串所有字符转换为大写，得到sign值signValue。
     * ◆ key设置路径：微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
     * 参数具体变化情况
     * stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
     * stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注：key为商户平台设置的密钥key
     * sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7" //注：MD5签名方式
     *
     * @param table
     * @return
     */
    public static String getPreOrderSign(HashMap<String, String> table) {
        TreeMap<String, String> tree = new TreeMap<String, String>();
        if (table != null) {
            Set<Map.Entry<String, String>> enu = table.entrySet();
            for (Map.Entry<String, String> item : enu) {
                if (!StringUtils.isEmpty(item.getValue())) {//为空的过滤掉
                    tree.put(item.getKey(), item.getValue());
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        Set<String> keys = tree.keySet();
        int index = 0;
        for (String key : keys) {
            if (index != 0) {
                sb.append("&");
            }
            sb.append(key).append("=").append(tree.get(key));
            index++;
        }
        sb.append("&key=").append(MCH_KEY);
        return MD5Util.getMD5(sb.toString()).toUpperCase();
    }

    /**
     * 获取返回给小程序必要的签名的信息
     * @param timeStamp
     * 注意这里的时间戳是服务器返回给客户端，签名中使用和返回一致，并且注意这里是使用秒 而不是毫秒
     * prepay_id= 的封装前面加了个package=
     * @return
     */
    public static String getReturnPaySign(String nonceStr, String prepay_id, String signType, long timeStamp) {
        String sb = "appId=" + MINI_APP_ID +
                "&nonceStr=" + nonceStr +
                "&package=prepay_id=" + prepay_id +
                "&signType=" + signType +
                "&timeStamp=" + timeStamp +
                "&key=" + MCH_KEY;
        return MD5Util.getMD5(sb).toUpperCase();
    }


    /**生成一个唯一的订单号
     * 当前时间戳 + 4位随机字符
     * */
    public static String generateOrderID(){
        Calendar calendar = Calendar.getInstance();
        StringBuilder dateStr = new StringBuilder();
        dateStr.append(StringUtils.getDateString(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1,
                calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND)));
        dateStr.append(StringUtils.int2String3(calendar.get(Calendar.MILLISECOND)));
        dateStr.append(getRandomString(4));
        return dateStr.toString();
    }


    /**生成订单 交易起始时间 和 交易结束时间*/
    public static String[] generateOrderTime(){
        String[] time = new String[2];
        Calendar calendar = Calendar.getInstance();
        time[0] = StringUtils.getDateString(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1,
                calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));

        calendar.add(Calendar.MINUTE, ORDER_EXPIRE_TIME_MINUTE);
        time[1] = StringUtils.getDateString(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1,
                calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
        return time;
    }



}
